package com.qf.business.message.netty;

import com.qf.business.message.handler.TextMsgChannelHandler;
import com.qf.business.message.handler.TextOutChannelHandler;
import com.qf.business.message.handler.base.BaseMsgChannelHandler;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.http.HttpObjectAggregator;
import io.netty.handler.codec.http.HttpServerCodec;
import io.netty.handler.codec.http.websocketx.WebSocketServerProtocolHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;

import javax.annotation.PostConstruct;
import java.util.List;

/**
 * Netty服务端
 * author Ken
 * create_time 2023/1/6
 */
@Component
@Slf4j
public class NettyServer {

    private ServerBootstrap bootstrap;

    private EventLoopGroup master = new NioEventLoopGroup();
    private EventLoopGroup slave = new NioEventLoopGroup();

    @Value("${netty.port}")
    private Integer port;
    
    @Autowired(required = false)
    private List<BaseMsgChannelHandler> channelHandlerList;

    /**
     * 当前Bean对象注入完属性后，进行初始化操作
     */
    @PostConstruct
    public void init(){
        bootstrap = new ServerBootstrap()
                .group(master, slave)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer() {
                    @Override
                    protected void initChannel(Channel ch) throws Exception {
                        ChannelPipeline pipeline = ch.pipeline();
                        pipeline.addLast(new HttpServerCodec());
                        pipeline.addLast(new HttpObjectAggregator(1024 * 1024 * 10));
                        pipeline.addLast(new WebSocketServerProtocolHandler("/"));

                        //自定义相关的ChannelHandler
                        pipeline.addLast(new TextMsgChannelHandler());
                        pipeline.addLast(new TextOutChannelHandler());

                        if (CollectionUtils.isEmpty(channelHandlerList)) return;
                        for (BaseMsgChannelHandler baseMsgChannelHandler : channelHandlerList) {
                            pipeline.addLast(baseMsgChannelHandler);
                        }
                    }
                });
    }

    /**
     * 启动Netty服务
     */
    public void start(){
        bootstrap.bind(port).addListener(future ->  {
           if (future.isSuccess()) {
               log.debug("[Netty Server Start] 信令服务器启动成功！端口：{}", port);
           } else {
               log.error("[Netty Server Start] 信令服务器启动失败", future.cause());
           }
        });
    }
}
